package com.blackhorse.controller;

import com.blackhorse.domain.UserB;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

import java.util.Date;
import java.util.Map;

/**
 * SpringMVC常用注解
 */
@Controller
@RequestMapping("/anno")
@SessionAttributes("msg")//把request域中的msg信息存入session域
public class AnnoController {
    /**
     * 当请求参数名和方法参数名不一致时，无法完成请求参数的自动封装
     *
     * @param username
     * @return
     * @RequestParam 注解将请求参数name的值封装为username的值
     * name属性表示请求参数名，required属性表示该请求参数是否必须，默认为true
     */
    @RequestMapping("/testRequestParam")
    public String testRequestParam(@RequestParam(name = "name", required = true) String username) {
        System.out.println("testRequestParam方法请求参数：" + username);
        return "success";
    }

    /**
     * @param body
     * @return
     * @RequestBody 用于获取请求体(GET请求不可用 ）
     */
    @RequestMapping("/testRequestBody")
    public String testRequestBody(@RequestBody String body) {
        System.out.println("请求体：" + body);
        return "success";
    }

    /**
     * restful编程风格
     * 多个方法请求路径相同，依靠请求方式区分执行哪个方法
     * 当请求路径和请求方法都相同时，可以使用参数占位符（如{id}）区别
     * 如：
     * post请求的添加用户操作   path="/user"
     * get请求的查询所有用户操作  path="/user"
     * get请求的通过id查询用户操作 path="/user/{id}"
     * 例如：http://localhost:8080/user/12 表示查询id=12的用户的方法的路径
     *
     * @param id
     * @return
     * @PathVariable 用于取得参数占位符的值
     */
    @RequestMapping("/testPathVariable/{id}")
    public String testPathVariable(@PathVariable String id) {
        System.out.println("参数占位符的值：" + id);
        return "success";
    }

    /**
     * @param header
     * @return
     * @RequestMapping 获取请求头信息 name/value属性：指定获得请求头的名称
     */
    @RequestMapping("/testRequestHeader")
    public String testRequestHeader(@RequestHeader("Accept") String header) {
        System.out.println("请求头Accept：" + header);
        return "success";
    }

    /**
     * @param cookieValue
     * @return
     * @CookieValue 获取Cookie的值 name/value属性：表示要获取Cookie的名称
     */
    @RequestMapping("/testCookieValue")
    public String testCookieValue(@CookieValue("JSESSIONID") String cookieValue) {
        System.out.println("Cookie名为JSESSIONID的值：" + cookieValue);
        return "success";
    }

    /**
     * @return
     * @ModelAttribute 被该注解标注的方法会在控制器方法前执行
     * 1）控制器方法会将@ModelAttribute修饰的方法的返回值接收为方法参数，
     * 并根据请求参数再次封装方法参数对象
     * 2）当@ModelAttribute修饰的方法无返回时，需要用@ModelAttribute("xxx")修饰参数，xxx为存入map集合的对象的key
     */
    @RequestMapping("/testModelAttribute")
    public String testModelAttribute(/*@ModelAttribute("user")*/ UserB user) {
        System.out.println("控制器方法执行了...");
        System.out.println("封装好的User信息：" + user);
        return "success";
    }

    /**
     * @ModelAttribute 被该注解标注的方法会在控制器方法前执行
     * 假设该方法用于当用户提交信息不完全时，未被提交的属性注入数据库信息
     * 1)方法有返回值时，其返回值会被控制器方法参数接收
     */
    @ModelAttribute
    public UserB initUser(String name) {
        //假设根据name查询User的数据库信息并封装对象
        //UserB user = userDao.findUserByName(name);
        UserB user = new UserB();
        user.setName(name);
        user.setAge(28);//假设数据库信息是28
        user.setBirthday(new Date(0));//假设数据库信息是1970-01-01 08:00:00
        System.out.println("被@ModelAttribute注释的有返回方法执行了...");
        return user;
    }


    /**
     * 2)方法没有返回值时，可以在参数中添加Map集合用于存储封装的User信息
     */
    /*
    @ModelAttribute
    public void initUser(String name, Map<String, UserB> map) {
        //假设根据name查询User的数据库信息并封装对象
        //UserB user = userDao.findUserByName(name);
        UserB user = new UserB();
        user.setName(name);
        user.setAge(28);//假设数据库信息是28
        user.setBirthday(new Date(0));//假设数据库信息是1970-01-01 08:00:00
        map.put("user", user);
        System.out.println("被@ModelAttribute注释的无返回方法执行了...");
    }
     */

    /**
     * @SessionAttributes 注解用于向session域中存入信息，只能用在类上
     * 向session中添加信息（注意本类的@SessionAttributes注解）
     */
    @RequestMapping("/testSessionAttributes")
    public String testSessionAttributes(Model model) {
        System.out.println("testSessionAttributes方法执行了...");
        //相当于底层在request域中添加信息
        model.addAttribute("msg", "美美");
        return "success";
    }

    /**
     * 获取session中信息
     * @param model
     * @return
     */
    @RequestMapping("/getSessionAttributes")
    public String getSessionAttributes(Model model) {
        System.out.println("getSessionAttributes方法执行了...");
        //在session域中获取msg信息
        ModelMap modelMap = (ModelMap) model;
        String msg = (String) modelMap.get("msg");
        System.out.println("session中的msg信息:" + msg);
        return "success";
    }


    /**
     * 清除session中信息
     */
    @RequestMapping("/clearSessionAttributes")
    public String clearSessionAttributes(SessionStatus status) {
        System.out.println("clearSessionAttributes方法执行了...");
        status.setComplete();//清除session中的信息
        return "success";
    }
}
